package cn.itsource.config;

import cn.itsource.result.JSONResult;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.web.reactive.error.ErrorWebExceptionHandler;
import org.springframework.core.annotation.Order;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.server.ResponseStatusException;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import reactor.netty.ByteBufMono;

@Component
@Order(-1)
@Slf4j
public class GatewayExceptionHandler implements ErrorWebExceptionHandler {


    @Override
    public Mono<Void> handle(ServerWebExchange exchange, Throwable ex) {
        //拿到请求和响应
        ServerHttpResponse response = exchange.getResponse();
        ServerHttpRequest request = exchange.getRequest();
        log.error("ErrorWebExceptionHandler 发生异常 {} ，{} ，{}", request.getURI(), request.getMethod(), ex.getMessage());
        
        //处理异常，包装结果
        JSONResult jsonResult = null;
        if (ex instanceof ResponseStatusException) {
            jsonResult = JSONResult.builder().success(false)
                    .message(((ResponseStatusException) ex).getReason())
                    .code(((ResponseStatusException) ex).getStatus().value())
                    .build();
        } else {
            jsonResult = JSONResult.builder().success(false).message(ex.getMessage()).code(500).build();
        }
        
        //以JSON方式把异常写出去
        DataBuffer dataBuffer = response.bufferFactory()
                .allocateBuffer().write(JSON.toJSONString(jsonResult).getBytes());
        response.setStatusCode(HttpStatus.OK);
        //基于流形式
        response.getHeaders().setContentType(MediaType.APPLICATION_JSON);
        return response.writeAndFlushWith(Mono.just(ByteBufMono.just(dataBuffer)));
    }

    //处理系统异常，兜底处理所有的一切
    @ExceptionHandler(value = Exception.class)
    public  JSONResult defaultExceptionHandler(ServerWebExchange exchange,Throwable ex) {
        ServerHttpRequest request = exchange.getRequest();
        log.error("全局异常捕获 {} ，{} ，{}", request.getURI(), request.getMethod(), ex);
        return JSONResult.builder().success(false).message(ex.getMessage()).code(200).build();
    }
}